package com.suian.spring.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogAspect {
    private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);

    //不符合AOP规范不建议用
//    private static final String POINT_CUT = "execution(* com.suian.spring.service..*(..))";

//    @Pointcut("execution(* com.suian.spring.service..*(..))")
    public void serviceMethods() {}

    @Before("serviceMethods")
    public void beforeAdvice(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        logger.info("方法 {} 开始执行", methodName);
    }

    @After("serviceMethods")
    public void afterAdvice(JoinPoint joinPoint) {
        String methodName = joinPoint.getSignature().getName();
        logger.info("方法 {} 执行结束", methodName);
    }

    // 记录正常返回结果
    @AfterReturning(pointcut = "serviceMethods()", returning = "result")
    public void afterReturningAdvice(JoinPoint joinPoint, Object result) {
        String methodName = joinPoint.getSignature().getName();
        logger.info("方法 [{}] 正常返回，结果: {}", methodName, result);
    }

    // 记录异常信息
    @AfterThrowing(pointcut = "serviceMethods()", throwing = "ex")
    public void afterThrowingAdvice(JoinPoint joinPoint, Exception ex) {
        String methodName = joinPoint.getSignature().getName();
        logger.error("方法 [{}] 执行异常，错误信息: {}", methodName, ex.getMessage(), ex);
    }

    @Around("serviceMethods()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        String methodName = joinPoint.getSignature().getName();
        logger.info("开始执行方法: {}", methodName);
        try {
            Object result = joinPoint.proceed();
            long elapsedTime = System.currentTimeMillis() - startTime;
            logger.info("方法 [{}] 执行耗时: {} ms", methodName, elapsedTime);
            return result;
        } catch (Throwable e) {
            logger.error("方法 [{}] 执行异常", methodName, e);
            throw e;
        }
    }
}
